﻿
if (typeof jQuery === 'undefined') {
    throw new Error('jquery.alert JavaScript requires jQuery');
}

if (typeof Plugin === 'undefined') {
    throw new Error('jquery.alert JavaScript requires Plugin');
}

(function ($) {
    'use strict';

    var Alert = function (el, options) {
        this.$el = $(el);
        this.defaults = _config_.alert.defaults;
        this.methods = _config_.alert.methods;
        this.events = _config_.alert.events;
        this.initials = $.com.getDataBindFromElement(this.$el);
        this.originals = $.extend(true, {}, this.defaults, this.initials);
        this.options = $.extend(true, {}, this.originals, options);
        this.options.serial = $.com.getSerial(16);
        this.init();
    };

    Alert.prototype = new Plugin();

    Alert.prototype.init = function () {
        this.$content = this.$el.find('.content');
        this.$icons = this.$content.find('.icon');
        this.$message = this.$content.find('.message');
        this.$buttons = this.$el.find('.actions [data-button]').button();
        this.initEvent();
    };

    Alert.prototype.refresh = function () {
        this.$icons.hide();
        this.$icons.filter('.' + this.options.type).show();
        this.$buttons.parent().show();
        this.$buttons.hide();
        this.options.text = this.options.text || '';
        this.$message.html(this.options.text);
        switch (this.options.type) {
            case 'info':
                this.$buttons.parent().hide();
                break;
            case 'success':
                this.$buttons.filter('[data-button="ok"]').show().find('.button-label').html('确定');
                break;
            case 'error':
            case 'warning':
                this.$buttons.filter('[data-button="close"]').show().find('.button-label').html('关闭');
                break;
            case 'question':
                this.$buttons.show().filter('[data-button="close"]').find('.button-label').html('取消');
                this.$buttons.filter('[data-button="ok"]').find('.button-label').html('确定');
                break;
            default:
                break;
        }

        //图标
        if ($.com.hasValue(this.options.icon)) {
            this.$icon.attr('class', this.options.icon);
        }

        //按钮文字
        if ($.com.hasValue(this.options.okText)) {
            this.$buttons.filter('[data-button="ok"]').find('.button-label').html(this.options.okText);
        }
        if ($.com.hasValue(this.options.closeText)) {
            this.$buttons.filter('[data-button="close"]').find('.button-label').html(this.options.closeText);
        }
    };

    Alert.prototype.initEvent = function () {
        var that = this;
        this.$el.off('open.' + this.namespace).on('open.' + this.namespace, function (event, args) {
            that.onOpen(event, args);
        });
        this.$el.off('ok.' + this.namespace).on('ok.' + this.namespace, function (event) {
            that.onOk(event);
        });
        this.$el.off('close.' + this.namespace).on('close.' + this.namespace, function (event) {
            that.onClose(event);
        });

        this.$buttons.filter('[data-button="ok"]').click(function (event) {
            that.trigger(event, 'ok');
        });
        this.$buttons.filter('[data-button="close"]').click(function (event) {
            that.trigger(event, 'close');
        });
    };

    Alert.prototype.onOpen = function (event, options) {
        this.options = $.extend(true, {}, this.originals, options);

        var ret = this.execute(this.options.opening, event);
        if ($.com.hasValue(ret) && ret === false) {
            return;
        }

        this.$el.modal('show');
        $('.modal-backdrop:last').css('z-index', '999998');
        this.refresh();

        this.execute(this.options.opened, event);

        if (this.options.autoClose) {
            var that = this;
            setTimeout(function () {
                if (that.options.type === 'success') {
                    that.onOk(event);
                } else {
                    that.onClose(event);
                }
            }, Number(this.options.timeout));
        }
    };

    Alert.prototype.onOk = function (event) {
        var ret = this.execute(this.options.closing, event);
        if ($.com.hasValue(ret) && ret === false) {
            return;
        }

        var ret = this.execute(this.options.confirming, event);
        if ($.com.hasValue(ret) && ret === false) {
            return;
        }

        this.$el.modal('hide');

        this.execute(this.options.confirmed, event);

        this.execute(this.options.closed, event);
    };

    Alert.prototype.onClose = function (event) {
        var args = {};
        var ret = this.execute(this.options.closing, event, args);
        if ($.com.hasValue(ret) && ret === false) {
            return;
        }

        var ret = this.execute(this.options.cancelling, event);
        if ($.com.hasValue(ret) && ret === false) {
            return;
        }

        this.$el.modal('hide');

        this.execute(this.options.cancelled, event);

        this.execute(this.options.closed, event, args);
    };

    $.fn.alert = function (options) {
        var args = Array.prototype.slice.call(arguments, 1);
        var value = undefined;
        this.each(function () {
            var $this = $(this);
            var data = $this.data(_config_.alert.namespace);
            // initial if nover
            if ($.com.isNullOrEmpty(data)) {
                data = new Alert(this, typeof options === 'object' && options);
                $this.data(_config_.alert.namespace, data);
            }

            if (typeof options === 'string') {
                //if options is not a method
                if ($.inArray(options, data.methods) < 0) {
                    throw 'Unknown method: ' + options;
                }

                //if options is a plugin method, to execute
                value = data[options].apply(data, args);
            }
        });

        return typeof value === 'undefined' ? this : value;
    };
})(jQuery);